home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1996 #1 / Amiga Plus CD - 1996 - No. 1.iso / pd / netz / xbtx_v1.1 / iorawserial.cpp < prev    next >
C/C++ Source or Header  |  1995-09-26  |  8KB  |  400 lines

  1. /*
  2. **    $Id: IORawSerial.cpp 1.3 1995/09/26 19:45:11 olsen Exp olsen $
  3. **
  4. **    :ts=4
  5. */
  6.  
  7. /*
  8.  * Copyright © 1995 by Olaf Barthel, All Rights Reserved
  9.  *
  10.  * Redistribution and use in source and binary forms, with or without
  11.  * modification, are permitted provided that the following conditions
  12.  * are met:
  13.  * 1. Redistributions of source code must retain the above copyright
  14.  *    notice, this list of conditions and the following disclaimer.
  15.  * 2. Redistributions in binary form must reproduce the above copyright
  16.  *    notice, this list of conditions and the following disclaimer in the
  17.  *    documentation and/or other materials provided with the distribution.
  18.  *
  19.  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
  20.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  21.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
  22.  * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  23.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  24.  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
  25.  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  26.  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  27.  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  28.  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29.  *
  30.  * This software has not been validated by the ``Bundesamt fuer Zulassungen in
  31.  * der Telekommunikation'' of the ``Deutsche Bundepost Telekom'' and thus
  32.  * must not be used for accessing the BTX-Network of the Telekom in Germany.
  33.  *
  34.  * Diese Software hat keine Zulassung durch das Bundesamt fuer Zulassungen in
  35.  * der Telekommunikation der Deutschen Bundespost Telekom und darf daher nicht
  36.  * am Netz der Deutschen Bundespost Telekom in Deutschland betrieben werden.
  37.  */
  38.  
  39. #include "IORawSerial.hpp"
  40.  
  41. #include <exec/memory.h>
  42. #include <exec/errors.h>
  43.  
  44. #include <devices/serial.h>
  45. #include <devices/timer.h>
  46.  
  47. #include <hardware/cia.h>
  48.  
  49. #include <clib/exec_protos.h>
  50.  
  51. #ifdef __SASC
  52. #include <pragmas/exec_pragmas.h>
  53.  
  54. extern struct ExecBase *SysBase;
  55. #endif    // _SASC
  56.  
  57. #include <string.h>
  58. #include <stdio.h>
  59.  
  60. VOID IORawSerial::StopRead(VOID)
  61. {
  62.     if(Valid && Reading)
  63.     {
  64.         if(!CheckIO((struct IORequest *)ReadRequest))
  65.             AbortIO((struct IORequest *)ReadRequest);
  66.  
  67.         WaitIO((struct IORequest *)ReadRequest);
  68.  
  69.         Reading = FALSE;
  70.     }
  71. }
  72.  
  73. VOID IORawSerial::StartRead(VOID)
  74. {
  75.     if(Valid)
  76.     {
  77.         StopRead();
  78.  
  79.         ReadRequest->IOSer.io_Command    = CMD_READ;
  80.         ReadRequest->IOSer.io_Data        = &SingleChar;
  81.         ReadRequest->IOSer.io_Length    = 1;
  82.  
  83.         SetSignal(0,ReadMask);
  84.  
  85.         SendIO((struct IORequest *)ReadRequest);
  86.  
  87.         Reading = TRUE;
  88.     }
  89. }
  90.  
  91. BYTE IORawSerial::WaitRead(VOID)
  92. {
  93.     BYTE Error;
  94.  
  95.     if(Valid)
  96.     {
  97.         if(Reading)
  98.         {
  99.             Error = WaitIO((struct IORequest *)ReadRequest);
  100.  
  101.             Reading = FALSE;
  102.         }
  103.         else
  104.             Error = 0;
  105.     }
  106.     else
  107.         Error = IOERR_OPENFAIL;
  108.  
  109.     return(Error);
  110. }
  111.  
  112. VOID IORawSerial::Close(VOID)
  113. {
  114.     if(Valid)
  115.     {
  116.         StopRead();
  117.         StopTime();
  118.  
  119.         CloseDevice((struct IORequest *)TimeRequest);
  120.  
  121.         DeleteIORequest((struct IORequest *)TimeRequest);
  122.  
  123.         DeleteMsgPort(TimePort);
  124.  
  125.         CloseDevice((struct IORequest *)ReadRequest);
  126.  
  127.         DeleteIORequest((struct IORequest *)ReadRequest);
  128.  
  129.         FreeVec(WriteRequest);
  130.  
  131.         DeleteMsgPort(WritePort);
  132.  
  133.         DeleteMsgPort(ReadPort);
  134.  
  135.         Valid = FALSE;
  136.     }
  137. }
  138.  
  139. LONG IORawSerial::Open(CONST STRPTR Channel,ULONG Unit,ULONG Baud,BOOL RTS_CTS)
  140. {
  141.     if(ReadPort = CreateMsgPort())
  142.     {
  143.         ReadMask = 1UL << ReadPort->mp_SigBit;
  144.  
  145.         if(WritePort = CreateMsgPort())
  146.         {
  147.             if(ReadRequest = (struct IOExtSer *)CreateIORequest(ReadPort,sizeof(struct IOExtSer)))
  148.             {
  149.                 if(WriteRequest = (struct IOExtSer *)AllocVec(sizeof(struct IOExtSer),MEMF_ANY | MEMF_PUBLIC))
  150.                 {
  151.                     if(!OpenDevice((UBYTE *)Channel,Unit,(struct IORequest *)ReadRequest,NULL))
  152.                     {
  153.                         ReadRequest->IOSer.io_Command    = SDCMD_SETPARAMS;
  154.                         ReadRequest->io_ExtFlags        = 0;
  155.                         ReadRequest->io_ReadLen            = 8;
  156.                         ReadRequest->io_WriteLen        = 8;
  157.                         ReadRequest->io_StopBits        = 1;
  158.  
  159.                         if(Baud)
  160.                             ReadRequest->io_Baud = Baud;
  161.  
  162.                         if(RTS_CTS >= FALSE)
  163.                         {
  164.                             if(RTS_CTS)
  165.                                 ReadRequest->io_SerFlags = (UBYTE)( ReadRequest->io_SerFlags | SERF_XDISABLED |   SERF_7WIRE);
  166.                             else
  167.                                 ReadRequest->io_SerFlags = (UBYTE)((ReadRequest->io_SerFlags | SERF_XDISABLED) & ~SERF_7WIRE);
  168.                         }
  169.                         else
  170.                             ReadRequest->io_SerFlags |= SERF_XDISABLED;
  171.  
  172.                         if(!DoIO((struct IORequest *)ReadRequest))
  173.                         {
  174.                             CopyMem(ReadRequest,WriteRequest,sizeof(struct IOExtSer));
  175.  
  176.                             WriteRequest->IOSer.io_Message.mn_ReplyPort = WritePort;
  177.  
  178.                             if(TimePort = CreateMsgPort())
  179.                             {
  180.                                 TimeMask = 1UL << TimePort->mp_SigBit;
  181.  
  182.                                 if(TimeRequest = (struct timerequest *)CreateIORequest(TimePort,sizeof(struct timerequest)))
  183.                                 {
  184.                                     if(!OpenDevice((UBYTE *)TIMERNAME,UNIT_VBLANK,(struct IORequest *)TimeRequest,NULL))
  185.                                     {
  186.                                         Valid = TRUE;
  187.  
  188.                                         StartRead();
  189.  
  190.                                         return(0);
  191.                                     }
  192.  
  193.                                     DeleteIORequest((struct IORequest *)TimeRequest);
  194.                                     TimeRequest = NULL;
  195.                                 }
  196.  
  197.                                 DeleteMsgPort(TimePort);
  198.                                 TimePort = NULL;
  199.                             }
  200.                         }
  201.  
  202.                         CloseDevice((struct IORequest *)ReadRequest);
  203.                     }
  204.  
  205.                     FreeVec(WriteRequest);
  206.                     WriteRequest = NULL;
  207.                 }
  208.  
  209.                 DeleteIORequest((struct IORequest *)ReadRequest);
  210.                 ReadRequest = NULL;
  211.             }
  212.  
  213.             DeleteMsgPort(WritePort);
  214.             WritePort = NULL;
  215.         }
  216.  
  217.         DeleteMsgPort(ReadPort);
  218.         ReadPort = NULL;
  219.     }
  220.  
  221.     return(-1);
  222. }
  223.  
  224. LONG IORawSerial::GetChar(LONG Timeout)
  225. {
  226.     LONG Result;
  227.  
  228.     if(Valid)
  229.     {
  230.         if(Reading)
  231.         {
  232.             if(CheckIO((struct IORequest *)ReadRequest))
  233.             {
  234.                 if(WaitRead())
  235.                     Result = CHANNELERR_Nothing;
  236.                 else
  237.                     Result = SingleChar;
  238.  
  239.                 StartRead();
  240.             }
  241.             else
  242.             {
  243.                 if(Timeout)
  244.                 {
  245.                     ULONG Signals;
  246.  
  247.                     StartTime(Timeout);
  248.  
  249.                     for(;;)
  250.                     {
  251.                         Signals = ::Wait(ReadMask | TimeMask);
  252.  
  253.                         if(Signals & ReadMask)
  254.                         {
  255.                             if(WaitRead())
  256.                                 Result = CHANNELERR_Nothing;
  257.                             else
  258.                                 Result = SingleChar;
  259.  
  260.                             StopTime();
  261.  
  262.                             StartRead();
  263.  
  264.                             break;
  265.                         }
  266.  
  267.                         if(Signals & TimeMask)
  268.                         {
  269.                             WaitTime();
  270.  
  271.                             Result = CHANNELERR_Timeout;
  272.  
  273.                             break;
  274.                         }
  275.                     }
  276.                 }
  277.                 else
  278.                     Result = CHANNELERR_Nothing;
  279.             }
  280.         }
  281.         else
  282.             Result = CHANNELERR_Nothing;
  283.     }
  284.     else
  285.         Result = CHANNELERR_EOF;
  286.  
  287.     return(Result);
  288. }
  289.  
  290. VOID IORawSerial::PutString(CONST STRPTR String,LONG Len)
  291. {
  292.     if(Valid)
  293.     {
  294.         if(Len < 0)
  295.             Len = strlen(String);
  296.  
  297.         WriteRequest->IOSer.io_Command    = CMD_WRITE;
  298.         WriteRequest->IOSer.io_Data     = (APTR)String;
  299.         WriteRequest->IOSer.io_Length    = Len;
  300.  
  301.         DoIO((struct IORequest *)WriteRequest);
  302.     }
  303. }
  304.  
  305. LONG IORawSerial::Waiting(VOID)
  306. {
  307.     if(Valid)
  308.     {
  309.         if(Reading)
  310.         {
  311.             if(CheckIO((struct IORequest *)ReadRequest))
  312.                 return(1);
  313.         }
  314.  
  315.         WriteRequest->IOSer.io_Command = SDCMD_QUERY;
  316.  
  317.         DoIO((struct IORequest *)WriteRequest);
  318.  
  319.         return((LONG)WriteRequest->IOSer.io_Actual);
  320.     }
  321.     else
  322.         return(0);
  323. }
  324.  
  325. ULONG IORawSerial::WaitMask(VOID)
  326. {
  327.     return(ReadMask);
  328. }
  329.  
  330. VOID IORawSerial::Wait(LONG Seconds)
  331. {
  332.     TimeRequest->tr_node.io_Command = TR_ADDREQUEST;
  333.     TimeRequest->tr_time.tv_secs    = Seconds;
  334.     TimeRequest->tr_time.tv_micro    = 0;
  335.  
  336.     DoIO((struct IORequest *)TimeRequest);
  337. }
  338.  
  339. IORawSerial::IORawSerial()
  340. {
  341.     Reading = Ticking = Valid = FALSE;
  342. }
  343.  
  344. IORawSerial::~IORawSerial()
  345. {
  346.     Close();
  347. }
  348.  
  349. VOID IORawSerial::StartTime(ULONG Seconds,ULONG Micros)
  350. {
  351.     StopTime();
  352.  
  353.     TimeRequest->tr_node.io_Command = TR_ADDREQUEST;
  354.     TimeRequest->tr_time.tv_secs    = Seconds;
  355.     TimeRequest->tr_time.tv_micro    = Micros;
  356.  
  357.     SetSignal(0,TimeMask);
  358.  
  359.     SendIO((struct IORequest *)TimeRequest);
  360.  
  361.     Ticking = TRUE;
  362. }
  363.  
  364. VOID IORawSerial::StopTime(VOID)
  365. {
  366.     if(Ticking)
  367.     {
  368.         if(!CheckIO((struct IORequest *)TimeRequest))
  369.             AbortIO((struct IORequest *)TimeRequest);
  370.  
  371.         WaitTime();
  372.     }
  373. }
  374.  
  375. VOID IORawSerial::WaitTime(VOID)
  376. {
  377.     if(Ticking)
  378.     {
  379.         WaitIO((struct IORequest *)TimeRequest);
  380.  
  381.         Ticking = FALSE;
  382.     }
  383. }
  384.  
  385. VOID IORawSerial::Flush(VOID)
  386. {
  387.     if(Valid)
  388.     {
  389.         BOOL IsReading = Reading;
  390.  
  391.         StopRead();
  392.  
  393.         WriteRequest->IOSer.io_Command = CMD_CLEAR;
  394.         DoIO((struct IORequest *)WriteRequest);
  395.  
  396.         if(IsReading)
  397.             StartRead();
  398.     }
  399. }
  400.